package cn.pconline.autoclub.task.data;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.pconline.autoclub.task.AppUtils;
import cn.pconline.autoclub.task.DBUtils;
import cn.pconline.autoclub.task.util.IdGeneratorByTable;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

public class SyncPost {
private static final Logger log = LoggerFactory.getLogger(SyncPost.class);
    
    private static IdGeneratorByTable idGenerator = new IdGeneratorByTable();
    //private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
    static List<String> replyColumns = null;

    static {
        try {
            replyColumns = DBUtils.getColumns("ac_dyna_reply");
        } catch (SQLException e) {
            log.error("get table columns error.", e);
        }
    }
    
    public static void main(String[] args) {
        AppUtils.initLog(SyncPost.class);
        //String text = "{\"agent\":0,\"authorId\":34564222,\"createAt\":1419996658000,\"createIp\":\"182.36.89.193\",\"floor\":14,\"forumId\":14140,\"forumName\":\"奥迪A6L论坛\",\"isQuote\":false,\"key\":\"autobbs.post.create61782600\",\"lastPostAt\":1419996658000,\"pid\":61782600,\"postAuthorId\":34564222,\"postAuthorName\":\"balba2008\",\"postFloor\":14,\"postId\":61782600,\"postMessage\":\"收心养性，专一点对人呗！心到分了五六处了\",\"quote\":{},\"tid\":6286512,\"title\":\"女朋友太漂亮了心里怕怕的怎么办？\",\"topicAuthorId\":33901648,\"topicCreateAt\":1419776842000,\"topicId\":6286512,\"topicReplyCount\":12,\"updateAt\":1419996658000,\"version\":1}";
        //JSONObject msg = JSON.parseObject(text);//new JSONObject();
        String fileName = null;
        if(args != null && args.length > 0) {
            fileName = args[0];
        }
        //fileName = "E:\\work\\autoclub\\branches\\autoclub_4.0_beta\\crontab\\task\\conf\\data.txt";
        if(fileName == null) {
            log.error("the file name must not be null, please input");
            return;
        }
        try {
            log.info("start sync topic");
            int count = readTopicData(fileName, new LineProcess() {
                public int process(String line) {
                    try {
                        JSONObject msg = JSON.parseObject(line);//new JSONObject();
                        log.info("topic: {}", msg);
                        return syncPost(msg);
                    } catch(RuntimeException ex) {
                        ex.printStackTrace();
                    }
                    return 0;
                }
            });
            log.info("add total: {}", count);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    
    private static int readTopicData(String fileName, LineProcess callback) throws IOException {
        @SuppressWarnings("resource")
        BufferedReader bufferedReader = new BufferedReader(new FileReader(fileName));
        String line = null;
        int count = 0;
        while((line = bufferedReader.readLine()) != null) {
            count += callback.process(line);
        }
        return count;
    }
    
    static interface LineProcess {
        public int process(String line);
    }


    private static int syncPost(JSONObject msg) {
        Connection conn = DBUtils.getConnection();
        long topicId = getTopicId(msg);
        long dynaId = getDynaIdByTopicId(conn, topicId);
        if(dynaId > 0) {
            long postId = msg.getLongValue("postId");
            long replyId = getReplyIdByTopicPostId(conn, dynaId, topicId, postId);
            if(replyId > 0) {
                log.info("the dyna-{} reply-{} exists", dynaId, replyId);
                return 0;
            }
            Map<String, Object> post = parsePost(msg, dynaId);
            try {
                return addReply(conn, post, dynaId);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } else {
            log.warn("not found topic-{} dyna", topicId);
        }
        return 0;
    }
    
    private static int addReply(Connection conn, Map<String, Object> post, long dynaId) throws SQLException {
        String sql = getSql("ac_dyna_reply_", dynaId);
        log.debug("add dyna reply\n sql: {}, \n data: {}", sql, post);
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(sql);
            int idx = 1;
            for(String col : replyColumns) {
                ps.setObject(idx++, post.get(col));
            }
            int count = ps.executeUpdate();
            log.info("add {} topic to dyna-{} reply-{}", count, dynaId, post.get("dyna_reply_id"));
            return count;
        } finally {
            DBUtils.releaseConn(null, ps, null);
        }
    }
    
    private static long getDynaIdByTopicId(Connection conn, long topicId) {
        String sql = "SELECT dyna_info_id FROM ac_dyna_info_2014 WHERE topic_id = ?";
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(sql);
            ps.setLong(1, topicId);
            ResultSet rs = ps.executeQuery();
            if(rs != null && rs.next()) {
                return rs.getLong(1);
            }
        } catch (SQLException e) {
            log.error("get dynaId by topicId-{} error.", topicId);
        }
        return 0;
    }
    
    private static long getReplyIdByTopicPostId(Connection conn, long dynaId, long topicId, long postId) {
        String table = "ac_dyna_reply_" + (dynaId%10);
        String sql = "SELECT dyna_info_id FROM "+table+" WHERE post_id = ? AND topic_id = ? AND dyna_info_id = ?";
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(sql);
            ps.setLong(1, dynaId);
            ResultSet rs = ps.executeQuery();
            if(rs != null && rs.next()) {
                return rs.getLong(1);
            }
        } catch (SQLException e) {
            log.error("get dyna-{} replyId by topicId-{},postId-{} error.", dynaId, topicId, postId);
        }
        return 0;
    }
    
    private static String getSql(String tablePrefix, long x) throws SQLException {
        StringBuilder dynaSqlBuilder = new StringBuilder("INSERT IGNORE INTO ");
        String table = tablePrefix + (x % 10);
        dynaSqlBuilder.append(table);
        List<String> columns = DBUtils.getColumns(table);
        StringBuilder dynaColumnBuilder = new StringBuilder();
        StringBuilder dynaParamBuilder = new StringBuilder();
        for(String col : columns) {
            dynaColumnBuilder.append(',').append(col);
            dynaParamBuilder.append(",?");
        }
        dynaSqlBuilder.append(" (").append(dynaColumnBuilder.substring(1));
        dynaSqlBuilder.append(") values (");
        dynaSqlBuilder.append(dynaParamBuilder.substring(1)).append(")");
        log.debug("club dyna insert sql: {}", dynaSqlBuilder);
        return dynaSqlBuilder.toString();
    }
    
    public static Map<String, Object> parsePost(JSONObject msg, long dynaId) {
        Map<String, Object> reply = new HashMap<String, Object>();
        String tableName = "ac_dyna_reply";
        reply.put("dyna_reply_id", idGenerator.generate(tableName, "dyna_reply_id"));
        reply.put("dyna_info_id", dynaId);
        reply.put("type", 1);
        reply.put("topic_id", getTopicId(msg));
        reply.put("post_id", msg.getLongValue("postId"));
        reply.put("floor", msg.getIntValue("postFloor"));
        reply.put("create_date", msg.getDate("lastPostAt"));
        reply.put("create_by", getUserId(msg));
        reply.put("create_name", msg.getString("postAuthorName"));

        boolean isQuote = msg.getBooleanValue("isQuote");
        if(isQuote) {
            JSONObject jsonQuote = JSONObject.parseObject(msg.getString("quote"));
            reply.put("post_to_dyna_reply_id", 0);
            reply.put("post_to_post_id", jsonQuote.getLongValue("quotePostId"));
            reply.put("post_to_user_id", jsonQuote.getLongValue("quotePostAuthorId"));
            reply.put("post_to_nick_name", jsonQuote.getString("quotePostAuthorName"));
            reply.put("post_to_floor", jsonQuote.getIntValue("quotePostFloor"));
        }

        reply.put("status", 1);
        String content = msg.getString("postMessage");
        reply.put("content", content);
        if (content != null && content.indexOf("[图]") != -1) {
            reply.put("is_pic", 1);
        } else {
            reply.put("is_pic", 0);
        }
        reply.put("censored", 1);
        reply.put("update_by", getUserId(msg));
        reply.put("create_at", msg.getDate("lastPostAt"));
        reply.put("update_at", msg.getDate("lastPostAt"));
        return reply;
    }
    
    private static long getTopicId(JSONObject msg) {
        return msg.getLongValue("topicId");
    }
    
    private static long getUserId(JSONObject msg) {
        return msg.getLongValue("postAuthorId");
    }
}
